package com.eternal.notification.model;

import android.annotation.SuppressLint;
import android.app.Application;
import androidx.lifecycle.MutableLiveData;
import androidx.annotation.NonNull;
import android.view.View;

import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.callback.NavCallback;
import com.alibaba.android.arouter.launcher.ARouter;
import com.eternal.base.data.NotificationRepository;
import com.eternal.base.data.ble.BleStatue;
import com.eternal.base.database.entity.Notification;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.global.BluetoothKey;
import com.eternal.base.protocol.ProtocolTransformer;
import com.eternal.base.router.RouterActivityPath;
import com.eternal.framework.binding.command.BindingAction;
import com.eternal.framework.binding.command.BindingCommand;
import com.eternal.framework.bus.Messenger;
import com.eternal.framework.bus.RxBus;
import com.eternal.framework.component.AppManager;
import com.eternal.framework.component.BaseViewModel;
import com.eternal.framework.utils.KLog;
import com.eternal.framework.utils.RxUtils;
import com.eternal.framework.utils.Utils;
import com.eternal.notification.R;
import com.eternal.notification.ui.NotificationActivity;
import com.google.common.primitives.UnsignedBytes;

import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by Administrator
 * On 2020/5/11
 * Description:
 * @author Administrator
 */
public class OtherModel extends BaseViewModel {
    public OtherModel(@NonNull Application application) {
        super(application);
        ok = Utils.getString(R.string.tip_ok);
        edit=Utils.getString(R.string.tip_edit);
        nameEdit.setValue(edit);
    }

    private String ok, edit;
    public boolean isDegree;
    private boolean isCreated;
    private NotificationRepository repository;
    private Notification notification;

    public MutableLiveData<String> nameEdit=new MutableLiveData<>();
    public MutableLiveData<String> name=new MutableLiveData<>();
    public MutableLiveData<Boolean> auto=new MutableLiveData<>();
    public MutableLiveData<Boolean> timeOn=new MutableLiveData<>();
    public MutableLiveData<Boolean> timeOff=new MutableLiveData<>();
    public MutableLiveData<Boolean> cycle=new MutableLiveData<>();
    public MutableLiveData<Boolean> schedule=new MutableLiveData<>();
    public MutableLiveData<Boolean> tmpHum=new MutableLiveData<>();
    public MutableLiveData<Boolean> hTmpSwitch=new MutableLiveData<>();
    public MutableLiveData<Boolean> lTmpSwitch=new MutableLiveData<>();
    public MutableLiveData<Boolean> hHumSwitch=new MutableLiveData<>();
    public MutableLiveData<Boolean> lHumSwitch=new MutableLiveData<>();
    public MutableLiveData<Character> hTmp=new MutableLiveData<>();
    public MutableLiveData<Character> lTmp=new MutableLiveData<>();
    public MutableLiveData<Byte> hHum=new MutableLiveData<>();
    public MutableLiveData<Byte> lHum=new MutableLiveData<>();

    public View.OnClickListener onEditName=new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(ok.equals(nameEdit.getValue())){
                nameEdit.setValue(edit);
                if(!notification.name.equals(name.getValue())){
                    repository.nameIsExists(notification.mac, notification.port,name.getValue())
                            .compose(RxUtils.<Boolean>bindToLifecycle(getLifecycleProvider()))
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new Consumer<Boolean>() {
                                @Override
                                public void accept(Boolean aBoolean) {
                                    if(aBoolean){
                                        name.setValue(notification.name);
                                        Messenger.getDefault().sendNoMsg(NotificationActivity.SHOW_NAME_EXISTS_DIALOG);
                                    } else {
                                        if (name.getValue().isEmpty()) {
                                            name.setValue(notification.name);
                                            Messenger.getDefault().sendNoMsg(NotificationActivity.SHOW_NAME_EMPTY_DIALOG);
                                        }
                                    }
                                }
                            });
                }
            }else{
                nameEdit.setValue(ok);
            }
        }
    };

    public BindingCommand<Void> onConfirm=new BindingCommand<Void>(new BindingAction() {
        @SuppressLint("CheckResult")
        @Override
        public void call() {
            BleStatue statue=repository.getConnect(notification.mac);
            if(statue!=null){
                final Notification temp=create();
                Single<Boolean> single;
                if(isCreated){
                    single=repository.saveNotification(statue, temp);
                }else{
                    single=repository.setNotification(statue, temp);
                }
                single.compose(RxUtils.<Boolean>bindToLifecycle(getLifecycleProvider()))
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<Boolean>() {
                            @Override
                            public void accept(Boolean aBoolean) throws Exception {
                                if(aBoolean){
                                    notification=temp;
                                    back();
                                }
                            }
                        });
            }
        }
    });

    public BindingCommand<Void> onCancel=new BindingCommand<Void>(new BindingAction() {
        @Override
        public void call() {
            ARouter.getInstance()
                    .build(RouterActivityPath.Detail.PAGE_DETAIL)
                    .withTransition(R.anim.left_in, R.anim.right_out)
                    .navigation(AppManager.getAppManager().currentActivity(), new NavCallback() {
                        @Override
                        public void onArrival(Postcard postcard) {
                            finish();
                        }
                    });
        }
    });

    public BindingCommand<Void> onDelete=new BindingCommand<Void>(new BindingAction() {
        @SuppressLint("CheckResult")
        @Override
        public void call() {
            Messenger.getDefault().sendNoMsg(NotificationActivity.SHOW_DELETE_DIALOG);
        }
    });

    private void back(){
        RxBus.getDefault().post(new ActivityEvent(ActivityEvent.NOTIFICATION_REFRESH));
        ARouter.getInstance()
                .build(RouterActivityPath.Detail.PAGE_DETAIL)
                .withTransition(R.anim.left_in, R.anim.right_out)
                .navigation(AppManager.getAppManager().currentActivity(), new NavCallback() {
                    @Override
                    public void onArrival(Postcard postcard) {
                        finish();
                    }
                });
    }

    public void init(NotificationRepository repository, String mac,byte port,
                     Notification notification, boolean isDegree, byte type){
        this.repository=repository;
        this.isDegree=isDegree;
        isCreated=false;
        if(notification==null){
            notification=new Notification();
            notification.type=type;
            notification.mac=mac;
            notification.port=port;
            notification.model=1;
            if(type==BluetoothKey.ALARMS){
                notification.name="New Alarm";
            }else{
                notification.name="New Notification";
            }
            notification.lHum=40;
            notification.hHum=90;
            if(isDegree){
                notification.lTmpC=0;
                notification.hTmpC=90;
                notification.lTmpF=32;
                notification.hTmpF= (byte) 194;
            }else{
                notification.lTmpF=40;
                notification.hTmpF=110;
                notification.lTmpC= (byte) Math.round(ProtocolTransformer.getDegree(40));
                notification.hTmpC= (byte) Math.round(ProtocolTransformer.getDegree(110));
            }
            notification.tmpHum=0xf;
            notification.open=true;
            isCreated=true;
        }
        this.notification=notification;
        init(notification);
    }

    private void init(@NonNull Notification notification){
        name.setValue(notification.name);
        tmpHum.setValue((notification.model&1)!=0);
        auto.setValue((notification.model&2)!=0);
        timeOn.setValue((notification.model&4)!=0);
        timeOff.setValue((notification.model&8)!=0);
        cycle.setValue((notification.model&16)!=0);
        schedule.setValue((notification.model&32)!=0);
        if(isDegree){
            hTmp.setValue((char) notification.hTmpC);
            lTmp.setValue((char) notification.lTmpC);
        }else{
            hTmp.setValue((char) UnsignedBytes.toInt(notification.hTmpF));
            lTmp.setValue((char) UnsignedBytes.toInt(notification.lTmpF));
        }
        hHum.setValue(notification.hHum);
        lHum.setValue(notification.lHum);
        hTmpSwitch.setValue((notification.tmpHum&8)!=0);
        lTmpSwitch.setValue((notification.tmpHum&4)!=0);
        hHumSwitch.setValue((notification.tmpHum&2)!=0);
        lHumSwitch.setValue((notification.tmpHum&1)!=0);
    }

    @SuppressLint("CheckResult")
    public void delete(){
        BleStatue statue=repository.getConnect(notification.mac);
        if(statue!=null){
            repository.removeNotification(statue, notification)
                    .compose(RxUtils.<Boolean>bindToLifecycle(getLifecycleProvider()))
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean aBoolean) {
                            if(aBoolean){
                                back();
                            }
                        }
                    });
        }
    }

    private Notification create(){
        Notification notification=new Notification();
        notification.mac=this.notification.mac;
        notification.port = this.notification.port;
        notification.type=this.notification.type;
        notification.id=this.notification.id;
        if(notification.type==BluetoothKey.ALARMS&& "New Alarm".equals(name.getValue())){
            notification.name=null;
        }else if(notification.type==BluetoothKey.NOTIFICATIONS&&"New Notification".equals(name.getValue())){
            notification.name=null;
        }else{
            notification.name=name.getValue();
        }
        notification.open=this.notification.open;
        if(tmpHum.getValue()){
            notification.model=1;
        }
        if(auto.getValue()){
            notification.model|=2;
        }
        if(timeOn.getValue()){
            notification.model|=4;
        }
        if(timeOff.getValue()){
            notification.model|=8;
        }
        if(cycle.getValue()){
            notification.model|=16;
        }
        if(schedule.getValue()){
            notification.model|=32;
        }
        char temp;
        if(isDegree){
            temp=hTmp.getValue();
            notification.hTmpC= (byte) temp;
            notification.hTmpF= (byte) ProtocolTransformer.getFah(temp);
            temp=lTmp.getValue();
            notification.lTmpC= (byte) temp;
            notification.lTmpF= (byte) ProtocolTransformer.getFah(temp);
        }else{
            temp=hTmp.getValue();
            notification.hTmpF= (byte) temp;
            notification.hTmpC= (byte) ProtocolTransformer.getDegree(temp);
            temp=lTmp.getValue();
            notification.lTmpF= (byte) temp;
            notification.lTmpC= (byte) ProtocolTransformer.getDegree(temp);
        }
        notification.hHum=hHum.getValue();
        notification.lHum=lHum.getValue();
        notification.tmpHum=0;
        if(hTmpSwitch.getValue()){
            notification.tmpHum|=8;
        }
        if(lTmpSwitch.getValue()){
            notification.tmpHum|=4;
        }
        if(hHumSwitch.getValue()){
            notification.tmpHum|=2;
        }
        if(lHumSwitch.getValue()){
            notification.tmpHum|=1;
        }
        return notification;
    }
}
